import asyncio
from datetime import datetime

import pytz
from django.core.paginator import Paginator
from django.db.models import Count
from django.db.models.functions import TruncDay, TruncMonth, TruncWeek
from django.db.models.query import QuerySet
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from django.views import View

from handler.handler import ScanHandler, SyncFileHandler, BucketFileManagement
from storage.iharbor_handler import create_bucket
from sync_web.models import BucketSyncBaseInfo


# Create your views here.


class SyncClientView(View):
    """显示同步配置列表"""

    def get(self, request, *args, **kwargs):
        obj = BucketSyncBaseInfo.objects.all()

        current_time = datetime.now()
        formatted_time = current_time.strftime('%Y-%m-%d-%H-%M-%S')
        dir_default = f'backup_{formatted_time}'

        paginator = Paginator(obj, 20)
        page_number = request.GET.get("page")
        page_obj = paginator.get_page(page_number)

        return render(request, 'sync_bucket_list.html', context={'page_obj': page_obj, 'dir_default': dir_default})

    def post(self, request, *args, **kwargs):
        sync_id = request.POST.get('sync_id')
        if not sync_id:
            return
        obj = BucketSyncBaseInfo.objects.filter(id=int(sync_id)).first()
        obj.sync_status = 1
        obj.save(update_fields=['sync_status'])

        # 启动同步服务
        ScanHandler(bucket_obj=obj).main()

        return JsonResponse({'tips_msg': f'同步任务以启动！'},
                            json_dumps_params={'ensure_ascii': False})


class SyncInfoView(View):
    """显示同步配置列表"""

    # def get(self, request, *args, **kwargs):
    #     # obj = BucketSyncBaseInfo.objects.all()
    #     return render(request, 'sync_bucket_list.html', context={})

    def post(self, request, *args, **kwargs):
        """添加备份配置"""
        bucket_name = request.POST.get('bucket_name')
        bash_url = request.POST.get('bash_url')
        local_dir = request.POST.get('local_dir')
        remote_path = request.POST.get('remote_path')
        bucket_token = request.POST.get('bucket_token')
        thread_num = request.POST.get('thread_num')

        if not bucket_name or not bash_url or not local_dir or not remote_path or not bucket_token:
            return JsonResponse({'tips_msg': f'配置信息填写不完整！'},
                                json_dumps_params={'ensure_ascii': False}, status=400)

        if ' ' in local_dir:
            local_dir = local_dir.replace(' ', '')

        if int(thread_num) <= 0:
            thread_num = 3

        try:
            create_bucket(bucket_name=bucket_name, bash_url=bash_url, local_dir=local_dir,
                          remote_path=remote_path,
                          bucket_token=bucket_token, sync_status=0, thread_num=int(thread_num))

        except Exception as e:

            return JsonResponse({'tips_msg': f'{str(e)}'},
                                json_dumps_params={'ensure_ascii': False}, status=400)

        return JsonResponse({'tips_msg': f'配置信息添加成功！'},
                            json_dumps_params={'ensure_ascii': False})


class SyncServerView(View):

    def post(self, request, *args, **kwargs):

        bucket_id = request.POST.get('bucket_id')
        if not bucket_id:
            return JsonResponse({'tips_msg': f'未获取相应的参数。'},
                                json_dumps_params={'ensure_ascii': False}, status=400)

        obj = BucketSyncBaseInfo.objects.filter(id=int(bucket_id)).first()
        if not obj:
            return JsonResponse({'tips_msg': f'未从数据库中获取相应的数据。'},
                                json_dumps_params={'ensure_ascii': False}, status=400)

        obj.sync_status = 1
        obj.save(update_fields=['sync_status'])

        asyncio.run(SyncFileHandler().worker(bucket=obj))

        return JsonResponse({'tips_msg': f'同步程序已启动！'},
                            json_dumps_params={'ensure_ascii': False})


class BucketStatustView(View):

    def get(self, request, *args, **kwargs):
        objs = BucketSyncBaseInfo.objects.all()
        d = {}
        for obj in objs:
            col_name = obj.get_bucket_table_name()
            bfm = BucketFileManagement(collection_name=col_name)
            model_class = bfm.get_sync_complete_obj()
            query = model_class.annotate(count=Count('id'))  # 同步量
            query2 = bfm.get_all_obj().annotate(count=Count('id'))  # 总量
            name = f'{obj.id}_{obj.bucket_name}'
            d[name] = [query, query2, obj.id]

        return render(request, 'bucket_statistics.html', context={'query_dict': d})


class StatistView(View):

    def get(self, request, *args, **kwargs):

        bucket_id = kwargs.get('pk')
        date_type = kwargs.get('type')

        if not bucket_id or not date_type:
            return

        try:
            obj = BucketSyncBaseInfo.objects.get(id=bucket_id)
        except Exception as e:
            return HttpResponse(status=400, content=f'查询备份桶错误 err={str(e)}')

        if not obj:
            return HttpResponse(status=400, content=f'未找到备份桶信息，请确认是否配置。')

        col_name = obj.get_bucket_table_name()
        bfm = BucketFileManagement(collection_name=col_name)
        model_class = bfm.get_sync_complete_obj()
        query = QuerySet().none()
        d = {}
        if date_type == 'month':
            query = model_class.annotate(file_num=TruncMonth('sync_time')).values('file_num').annotate(
                count=Count('id'))

        elif date_type == 'week':
            query = model_class.annotate(file_num=TruncWeek('sync_time')).values('file_num').annotate(
                count=Count('id'))
            pass
        elif date_type == 'day':
            query = model_class.annotate(file_num=TruncDay('sync_time')).values('file_num').annotate(
                count=Count('id'))

        # query = model_class.annotate(day_p=TruncDay('sync_time')).values('day_p').annotate(count=Count('id')).filter(sync_time__range=[date_time_start, date_time_end])

        paginator = Paginator(query, 20)
        page_number = request.GET.get("page")
        page_obj = paginator.get_page(page_number)

        return render(request, 'bucket_file_statistics.html',
                      context={'page_obj': page_obj, 'bucket_name': obj.bucket_name})

# class StatistView(View):
#
#     def get(self, request, *args, **kwargs):
#         date_time_start = request.GET.get('date_time_start')
#         date_time_end = request.GET.get('date_time_end')
#         backup_id = request.GET.get('backup_id')
#
#         if not date_time_start and not date_time_end:
#             date_time_start = datetime.now(tz=timezone.utc) + timedelta(days=1)
#             date_time_start = date_time_start.replace(hour=0, minute=0, second=0, microsecond=0)
#             date_time_end = datetime.now(tz=timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0)
#         else:
#             date_time_start = timezone.make_aware(datetime.strptime(date_time_start, '%Y-%m-%d'), timezone=pytz.UTC)
#             date_time_start = date_time_start.replace(hour=0, minute=0, second=0, microsecond=0)
#
#             date_time_end = timezone.make_aware(datetime.strptime(date_time_end, '%Y-%m-%d'), timezone=pytz.UTC)
#             date_time_end = date_time_end.replace(hour=23, minute=59, second=59, microsecond=0)
#
#         if not backup_id:
#             pass
#
#         objs = BucketSyncBaseInfo.objects.all()
#
#         l = []
#         for obj in objs:
#             col_name = obj.get_bucket_table_name()
#             bfm = BucketFileManagement(collection_name=col_name)
#             model_class = bfm.get_sync_complete_obj()
#             query = model_class.annotate(day_p=TruncDay('sync_time')).values('day_p').annotate(count=Count('id'))
#             print(query)
#
#             # query = model_class.annotate(day_p=TruncDay('sync_time')).values('day_p').annotate(count=Count('id')).filter(sync_time__range=[date_time_start, date_time_end])
#
#
#
#         return render(request, '', context={'query_obj': l})
